#include <string>
#include <iostream>
#include <thread>
using namespace std;

#include <boost/config.hpp>
#if !defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif

#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
//#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#define BOOST_THREAD_QUEUE_DEPRECATE_OLD

//#include <boost/thread/caller_context.hpp>
#include <boost/thread/executors/basic_thread_pool.hpp>
//#include <boost/thread/executors/loop_executor.hpp>
#include <boost/thread/executors/serial_executor.hpp>
#include <boost/thread/executors/inline_executor.hpp>
//#include <boost/thread/executors/thread_executor.hpp>
//#include <boost/thread/executors/executor.hpp>
//#include <boost/thread/executors/executor_adaptor.hpp>
//#include <boost/thread/executor.hpp>
#include <boost/thread/future.hpp>
//#include <boost/assert.hpp>

int main()
{
    int32_t thread_num = boost::thread::hardware_concurrency();

    cout << "thread_num:" << thread_num << endl;

    boost::executors::basic_thread_pool pool(thread_num);
    boost::executors::inline_executor iex;
    boost::executors::serial_executor sex(pool);

    cout << "main thread id:" << boost::this_thread::get_id() << endl;

    {
        auto f2 = boost::async(
                      sex,
                      []()
                      {
                          cout << "boost::this_thread::get_id():" << boost::this_thread::get_id() << endl;
                      })
                      .then(
                          iex,
                          [](boost::future<void> f)
                          {
                              cout << "boost::this_thread::get_id():" << boost::this_thread::get_id() << endl;
                          })
                      .then(
                          pool,
                          [](boost::future<void> f)
                          {
                              cout << "boost::this_thread::get_id():" << boost::this_thread::get_id() << endl;
                          });

        f2.wait();
    }

    {
        auto f2 = boost::async(
                      []()
                      {
                          cout << "boost::this_thread::get_id():" << boost::this_thread::get_id() << endl;
                      })
                      .then(
                          [](boost::future<void> f)
                          {
                              cout << "boost::this_thread::get_id():" << boost::this_thread::get_id() << endl;
                          })
                      .then(
                          [](boost::future<void> f)
                          {
                              cout << "boost::this_thread::get_id():" << boost::this_thread::get_id() << endl;
                          });

        f2.wait();
    }

    return 0;
}
